package spitzer.flair.widgets;

import java.util.Timer;
import java.util.TimerTask;

import org.eclipse.swt.SWT;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.OleControlSite;
import org.eclipse.swt.ole.win32.OleFrame;
import org.eclipse.swt.ole.win32.Variant;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;

public class FlashPlayer {

	private Composite parent;
	private Display display;
	private OleFrame frame;
	private OleControlSite flashPlayerControlSite;
	private OleAutomation player;

	private boolean created;
	private boolean loaded;
	private String moviePath;

	// Flash ActiveX constants	
    static final int ONREADYSTATECHANGE = -609;
    static final int READYSTATE = -525;
    static final int READY = 4;
    static final int SCALEMODE = 120;
    static final int ALIGNMODE = 121;
    static final int BACKGROUNDCOLOR = 123;
    static final int TOTALFRAMES = 124;
    static final int PLAYING = 125;
    static final int MOVIE = 102;
    static final int QUALITY = 105;
    static final int LOOP = 106;
    static final int FRAMENUM = 107;
    static final int SETZOOMRECT = 109;
    static final int PLAY = 112;
    static final int STOP = 113;
    static final int BACK = 114;
    static final int FORWARD = 115;
    static final int REWIND = 116;
    static final int ZOOM = 118;
    static final int PAN = 119;
    static final int STOPPLAY = 126;
    static final int GOTOFRAME = 127;
    static final int CURRENTFRAME = 128;
    static final int ISPLAYING = 129;
    static final int PERCENTLOADED = 130;
    static final int FRAMELOADED = 131;
    static final int FLASHVERSION = 132;
    static final int WMODE = 133;
    static final int SALIGN = 134;
    static final int MENU = 135;
    static final int BASE = 136;
    static final int SCALE = 137;
    static final int DEVICEFONT = 138;
    static final int EMBEDMOVIE = 139;
    static final int BGCOLOR = 140;
    static final int QUALITY2 = 141;
    static final int LOADMOVIE = 142;
    static final int TGOTOFRAME = 143;
    static final int TGOTOLABEL = 144;
    static final int TCURRENTFRAME = 145;
    static final int TCURRENTLABEL = 146;
    static final int TPLAY = 147;
    static final int TSTOPPLAY = 148;
    static final int SETVARIABLE = 151;
    static final int GETVARIABLE = 152;
    static final int TSETPROPERTY = 153;
    static final int TGETPROPERTY = 154;
    static final int TCALLFRAME = 155;
    static final int TCALLLABEL = 156;
    static final int TSETPROPERTYNUM = 157;
    static final int TGETPROPERTYNUM = 158;
    static final int SWREMOTE = 159;
    static final int FLASHVARS = 170;
	
	

	// TODO hadn't found a reference about the need in dispose listener
    /**    
	private class ParentDisposeListener implements DisposeListener {
    	public void widgetDisposed(DisposeEvent event) {
    		dispose();
    	}
	}
	**/
    
    public FlashPlayer(Composite parent, int style) {
		loaded = false;
		created = false;
		this.parent = parent;
		display = parent.getDisplay();
		// TODO hadn't found a reference about the need in dispose listener
        // parent.addDisposeListener(new ParentDisposeListener());
		createPlayer();
	}

	/** TODO find a portable way of interfacing flash
	 *  http://osflash.org/pipermail/osflash_osflash.org/2005-October/004506.html
	 *  **/
	private void createPlayer() {
		frame = new OleFrame(parent, SWT.NONE);
		frame.setSize(parent.getSize());
		flashPlayerControlSite = new OleControlSite(frame, SWT.NONE, "ShockwaveFlash.ShockwaveFlash");
		flashPlayerControlSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
        flashPlayerControlSite.setSize(parent.getSize());
        player = new OleAutomation(flashPlayerControlSite);
        created = true;
        
        if(moviePath != null) {
            setMovie(moviePath);
        }
	}
	
	private void destroyPlayer() {
		frame.dispose();
		frame = null;
		player.dispose();
		player = null;
		flashPlayerControlSite.deactivateInPlaceClient();
		flashPlayerControlSite = null;
		created = false;
		loaded = false;
	}
	
	private void dispose() {
		destroyPlayer();
	}
	
	public String getMovie() {
		return player.getProperty(MOVIE).getString();
	}
	
	public void	setMovie(String movie) {
		try {
			if (loaded) {
				moviePath = movie;
				recreate();
			} else {
				/** TODO ? what this branch is for **/
				player.setProperty(MOVIE, new Variant(movie));
                if(moviePath != null) {
                    moviePath = null;
                }
                loaded = true;				
			}
		} catch(Exception e) {
			System.out.print(e.getMessage());
		}
	}

	private void recreate() {
		destroyPlayer();
		Timer timer = new Timer();
		timer.schedule(new TimerTask(){
			public void run(){
				display.syncExec(new Runnable() {
					public void run() {
						createPlayer();
					}
				});
			}
		}, 100L);
	}
}
